package com.cy.member;

import java.awt.Color;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.Point;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.SwingConstants;

import com.cy.listener.ChessboardListener;
import com.cy.listener.SwitchControlPanelListener;
import com.cy.listener.SyncMoveListener;
import com.cy.member.parent.CYFrame;
import com.cy.member.parent.Chessman;
import com.cy.member.parent.ChineseChessman;

/**
 * 棋盘
 * @author CY
 */
public class Chessboard extends CYFrame {
	private static final long serialVersionUID = 1L;
	//棋盘坐标,用来保存每一个坐标所对应的像素值
	public static Point[][] sites = new Point[9][10];
	//棋盘的背景图
	private ImageIcon bgImg = new ImageIcon("image/main.gif");
	//用来容纳棋盘上的所有东西
	private Container container = this.getContentPane();
	//用来容纳棋子的容器
	private HashMap<Point, ChineseChessman> chineseChessmans = new HashMap<Point, ChineseChessman>();
	//提醒,用来提醒选择哪个棋子，移动了哪个棋子
	private Hint [] hints = new Hint[3];
	//显示谁赢
	private JLabel win = new JLabel("", SwingConstants.CENTER);
	
	static{
		//初始化坐标值
		initSite();
	}
	
	/**
	 * 构成函数，完成棋盘的创建
	 */
	public Chessboard() {
		//设置布局管理器
		container.setLayout(null);
		//开启新游戏
		newGame(true);
		//为棋盘添加一个监听器
		this.addMouseListener(new ChessboardListener());
		SyncMoveListener syncMoveListener = new SyncMoveListener();
		this.addWindowListener(new SyncMoveListener());
		this.addMouseListener(syncMoveListener);
		this.addMouseMotionListener(syncMoveListener);
		//设置鼠标样式
		this.setCursor(new Cursor(Cursor.HAND_CURSOR));
		//设置窗口的默认属性
		this.setIconImage(new ImageIcon("image/ico.png").getImage());
		this.setSize(bgImg.getIconWidth(),bgImg.getIconHeight());
		this.setTitle("中国象棋");
		//棋盘居中
		this.locationCenter();
	}
	
	/**
	 * 初始化坐标值
	 * 将屏幕上的每一个坐标的像素值保存到sites中
	 */
	private static void initSite() {
		int x = 52;
		int step = 57;
		//横坐标增长
		for(int i = 0; i < 9; i++) {
			int y = 54;
			//纵坐标增长
			for(int j = 0; j < 10; j++) {
				//过楚河汉界多1个像素
				if(j == 5) {
					y = y + 1;
				}
				sites[i][j] = new Point(x,y);
				y = y + step;
			}
			x = x + step;
		}
	}

	/**
	 * 将像素点转换为坐标点 
	 * 屏幕上的每一个像素所对应的坐标，如果没有对应则返回null
	 * @return 
	 */
	public static Point pixel2site(Point p) {
		int width = Chessman.getDimension().width/2;
		int height = Chessman.getDimension().height/2;
		for(int x = 0; x < sites.length; x++) {
			for(int y = 0; y < sites[x].length; y++) {
				Point point = sites[x][y];
				if(p.x>=point.x-width && p.x<=point.x+width && p.y>point.y-height && p.y<point.y+height) {
					return new Point(x,y);
				}
			}
		}
		return null;
	}
	
	/**
	 * 初始化棋子,经典模式
	 */
	private void initChessman() {
		//清空容纳棋子的容器
		chineseChessmans.clear();
		//创建棋子并添加到容器
		int x = 0, y = 0;
		//添加黑色棋子
		boolean who = false;
		for(int i = 0; i < 2; i++) {
			//添加车
			for(x = 0, y = (who?9:0) ; x <= 8; x = x + 8) {
				ChineseChessman che = new Che(who);
				che.getChessman().setSite(new Point(x,y));
				chineseChessmans.put(new Point(x,y), che);
			}
			//添加马
			for(x = 1, y = (who?9:0) ; x <= 7; x = x + 6) {
				ChineseChessman ma = new Ma(who);
				ma.getChessman().setSite(new Point(x,y));
				chineseChessmans.put(new Point(x,y), ma);
			}
			//添加象
			for(x = 2, y = (who?9:0) ; x <= 6; x = x + 4) {
				ChineseChessman xiang = new Xiang(who);
				xiang.getChessman().setSite(new Point(x,y));
				chineseChessmans.put(new Point(x,y), xiang);
			}
			//添加士
			for(x =3, y = (who?9:0) ; x <= 5; x = x + 2) {
				ChineseChessman shi = new Shi(who);
				shi.getChessman().setSite(new Point(x,y));
				chineseChessmans.put(new Point(x,y), shi);
			}
			//添加将
			for(x = 4, y = (who?9:0) ; x <= 4; x++){
				ChineseChessman jiang = new Jiang(who);
				jiang.getChessman().setSite(new Point(x,y));
				chineseChessmans.put(new Point(x,y), jiang);
			}
			//添加炮
			for(x = 1, y = (who?7:2); x <= 7; x = x + 6) {
				ChineseChessman pao = new Pao(who);
				pao.getChessman().setSite(new Point(x,y));
				chineseChessmans.put(new Point(x,y), pao);
			}
			//添加卒
			for(x = 0, y = (who?6:3); x <= 8; x = x + 2) {
				//通过异或来改变卒子在上还是在下
				ChineseChessman zu = new Zu(who);
				zu.getChessman().setSite(new Point(x,y));
				chineseChessmans.put(new Point(x,y), zu);
			}
			//添加红色棋子
			who = !who;
		}
	}
	
	/**
	 * 初始化棋子,流行模式
	 * @param type
	 */
	private void initChessman(boolean type) {
		//清空容纳棋子的容器
		chineseChessmans.clear();
		//创建棋子并添加到容器
		int x = 0, y = 0;
		//添加黑色棋子
		boolean who = false;
		for(int i = 0; i < 2; i++) {
			//添加车
			for(x = 0, y = (who?9:0) ; x <= 8; x = x + 8) {
				CreateUnknownChessman(x, y, who);
			}
			//添加马
			for(x = 1, y = (who?9:0) ; x <= 7; x = x + 6) {
				CreateUnknownChessman(x, y, who);
			}
			//添加象
			for(x = 2, y = (who?9:0) ; x <= 6; x = x + 4) {
				CreateUnknownChessman(x, y, who);
			}
			//添加士
			for(x =3, y = (who?9:0) ; x <= 5; x = x + 2) {
				CreateUnknownChessman(x, y, who);
			}
			//添加将
			for(x = 4, y = (who?9:0) ; x <= 4; x++){
				CreateUnknownChessman(x, y, who);
			}
			//添加炮
			for(x = 1, y = (who?7:2); x <= 7; x = x + 6) {
				CreateUnknownChessman(x, y, who);
			}
			//添加卒
			for(x = 0, y = (who?6:3); x <= 8; x = x + 2) {
				CreateUnknownChessman(x, y, who);
			}
			//添加红色棋子
			who = !who;
		}
	}

	/**
	 * 生成一个未知的棋子,被initChessman(boolean type)调用
	 * @param x
	 * @param y
	 * @param who
	 */
	private void CreateUnknownChessman(int x, int y, boolean who) {
		ChineseChessman chessman = new ChineseChessman();
		chessman.generateChessman(who);
		chessman.getChessman().setSite(new Point(x,y));
		chineseChessmans.put(new Point(x,y), chessman);
	}
	
	/**
	 * 初始化hint
	 */
	private void initHint() {
		hints[0] = new Hint(new ImageIcon("image/bluehint.png"));
		hints[1] = new Hint(new ImageIcon("image/redhint.png"));
		hints[2] = new Hint(new ImageIcon("image/redhint.png"));
		for(Hint hint : hints) {
			hint.setVisible(false);
		}
	}
	
	/**
	 * 初始化棋盘
	 */
	private void initChessboard() {
		container.removeAll();
		//添加赢
		win.setVisible(false);
		win.setBounds(0, 0, 558, 620);
		container.add(win);
		//添加棋子
		Iterator<Map.Entry<Point, ChineseChessman>> iter = chineseChessmans.entrySet().iterator();
		while(iter.hasNext()){
			Map.Entry<Point, ChineseChessman> entry = (Map.Entry<Point, ChineseChessman>)iter.next();
			container.add(entry.getValue().getChessman());
		}
		//添加hint
		for(Hint hint : hints) {
			container.add(hint);
		}
		//控制面板开关
		ImageIcon switchoverControlPanelImg = new ImageIcon("image/left.png");
		JLabel switchoverControlPanel = new JLabel(switchoverControlPanelImg);
		switchoverControlPanel.setBounds(bgImg.getIconWidth()-20, 5, switchoverControlPanelImg.getIconWidth(), switchoverControlPanelImg.getIconHeight());
		switchoverControlPanel.addMouseListener(new SwitchControlPanelListener());
		container.add(switchoverControlPanel);
		//添加棋盘背景
		JLabel background = new JLabel(bgImg);
		background.setBounds(0, 0, bgImg.getIconWidth(), bgImg.getIconHeight());
		container.add(background);
	}
	
	/**
	 * 修改棋盘上的Hint
	 * @param site 目标位置
	 * @param type 修改的hint类型,true移动性修改，false选择性修改
	 */
	private void setHint(Point site,boolean type) {
		//修改为移动性Hint
		if(type) {
			hints[0].setVisible(false);
			hints[1].setSite(hints[0].getSite());
			hints[1].setVisible(true);
			hints[2].setSite(site);
			hints[2].setVisible(true);
		} else {//修改为选择性Hint
			hints[0].setSite(site);
			hints[0].setVisible(true);
			hints[1].setVisible(false);
			hints[2].setVisible(false);
		}
	}
	
	/**
	 *  棋盘2个坐标之间所拥有的棋子
	 * @param origin 起始坐标
	 * @param target 目标坐标
	 * @return
	 */
	private ArrayList<Point> p2pChessman(Point origin, Point target) {
		ArrayList<Point> points = new ArrayList<Point>();
		int x = 0;
		int y = 0;
		int width  = origin.x - target.x;
		int height = origin.y - target.y;
		if(width < 0) {
			x = origin.x;
			width = -1*width;
		} else {
			x = target.x;
		}
		if(height < 0) {
			y = origin.y;
			height = -1*height;
		} else {
			y = target.y;
		}
		//遍历矩形
		for(int i = x;i <= width + x; i ++) {
			for(int j = y; j <= height + y; j++) {
				Point p = new Point(i,j);
				if(chineseChessmans.containsKey(p)){
					points.add(p);
				}
			}
		}
		return points;
	}
	
	/**
	 * 选择棋子
	 * @param chessman
	 */
	public void selectChessman(ChineseChessman chessman) {
		setHint(chessman.getChessman().getSite(), false);
	}
	
	/**
	 * 移动棋子
	 * @param chineseChessman
	 * @param target
	 */
	public boolean moveChineseChessman(ChineseChessman chineseChessman, Point target) {
		//保存棋子的原来位置
		Point p = chineseChessman.getChessman().getSite();
		//获取两点之间存在的棋子
		ArrayList<Point> ches = p2pChessman(p, target);
		
		//棋子移动成功
		if(chineseChessman.move(target,ches)){
			//删除该棋子在原来位置上的键值对
			chineseChessmans.remove(p);
			//将该棋子新的位置的键值对存放到棋子容器中
			chineseChessmans.put(target, chineseChessman);
			//修改提醒方式
			setHint(target, true);
			return true;
		} else {//移动失败
			return false;
		}
	}
	
	/**
	 * 吃子
	 * @param chineseChessman 准备要吃的棋子
	 * @param target 准备被吃掉的棋子
	 * @return 是否可以被吃掉
	 */
	public boolean eatChineseChessman(ChineseChessman chineseChessman, ChineseChessman target) {
		if(moveChineseChessman(chineseChessman, target.getChessman().getSite())) {
			//隐藏棋子
			target.getChessman().setLocation(-100, -100);
			//从棋盘中删除
//			container.remove(target.getChessman());
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * 悔棋
	 * @param step
	 */
	public void back(Step step) {
		chineseChessmans.remove(step.getChineseChessman().getChessman().getSite());
		chineseChessmans.put(step.getStart(), step.getChineseChessman());
		step.getChineseChessman().getChessman().setSite(step.getStart());
		hints[0].setVisible(false);
		hints[1].setVisible(true);
		hints[1].setSite(step.getStart());
		hints[2].setVisible(true);
		hints[2].setSite(step.getEnd());
		//吃子了
		if(step.getKilled() != null) {
			chineseChessmans.put(step.getEnd(),step.getKilled());
			step.getKilled().getChessman().setSite(step.getEnd());
		} 
	}
	
	/**
	 * 新游戏
	 */
	public void newGame(boolean type) {
		//经典模式
		if(type) {
			//初始化棋子
			initChessman();
		} else {//流行模式
			initChessman(false);
		}
		//初始化hint
		initHint();
		//初始化棋盘
		initChessboard();
	}
	
	/**
	 * 通过坐标，获取棋子
	 * @param point
	 * @return
	 */
	public ChineseChessman getChineseChessman(Point point) {
		return chineseChessmans.get(point);
	}
	
	/**
	 * 显示谁胜利
	 * @param who
	 */
	public void setWin(boolean who) {
		Font font = new Font("楷体", 1, 100);
		win.setFont(font);
		if(who) {
			win.setForeground(Color.red);
			win.setText("红方胜");
		} else {
			win.setForeground(Color.black);
			win.setText("黑方胜");
		}
		win.setVisible(true);
	}

	/**
	 * 替换棋子
	 * @param replace 新棋子
	 * @param replaced 要被替换掉的棋子
	 */
	public void replaceChessman(ChineseChessman replace, ChineseChessman replaced) {
		chineseChessmans.put(replaced.getChessman().getSite(), replace);
	}
}
